/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.common.utils;

import vip.dexian.common.query.Order;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 排序工具类。 默认情况下如果实体类继承自OrderEntity， 按照 order属性排序（升序，排序最小在前）。如果继承自BaseEntity，按照id排序（降序，id最大在前）
 *
 * @author 挺好的 2023年05月31日 11:14
 */
@Slf4j
public final class OrderUtils {

    /**
     * 排序条件
     */
    private List <Order> orders;

    private OrderUtils () {
        this.orders = new ArrayList <>();
    }

    /**
     * 创建一个Builder
     *
     * @return 排序工具类
     */
    public static OrderUtils builder () {
        return new OrderUtils();
    }

    /**
     * 升序排列
     *
     * @param property
     *         属性名称
     *
     * @return {@link vip.dexian.common.utils.OrderUtils}
     */
    public OrderUtils asc (String property) {
        return this.add(property, Order.Direction.ASC);
    }

    /**
     * 降序排列
     *
     * @param property
     *         属性名称
     *
     * @return {@link vip.dexian.common.utils.OrderUtils}
     */
    public OrderUtils desc (String property) {
        return this.add(property, Order.Direction.DESC);
    }

    /**
     * 添加Order，该方法不会检测是否添加了重复的排序（即property一样），添加的时候要注意是否添加了多个一样的条件
     *
     * @param order
     *         排序条件
     *
     * @return {@link vip.dexian.common.utils.OrderUtils}
     */
    public OrderUtils add (Order order) {

        if (!order.isValid()) {
            return this;
        }

        this.orders.add(order);

        return this;
    }

    /**
     * 返回排序列表(ArrayList)
     *
     * @return 排序列表
     */
    public List <Order> build () {
        return this.orders;
    }

    /**
     * 添加排序
     *
     * @param property
     *         属性名称
     * @param direction
     *         排序方向
     *
     * @return {@link vip.dexian.common.utils.OrderUtils}
     */
    private OrderUtils add (String property, Order.Direction direction) {
        log.debug("property({}), direction({}), ", property, direction);

        if (!this.isValid(property, direction)) {
            return this;
        }

        Order order = new Order(property, direction);

        return this.add(order);
    }

    /**
     * 是否有效
     *
     * @param property
     *         属性名称
     * @param direction
     *         排序方向
     *
     * @return property is empty || direction == null, return false。
     */
    private boolean isValid (String property, Order.Direction direction) {
        return StringUtils.isNotEmpty(property) && direction != null;
    }
}
